<?php
/**
 * php中的多进程
 */
/*$max = 800000;
$workers = 20;
$pids = array();
for($i = 0; $i < $workers; $i++){
    $pids[$i] = pcntl_fork();
    switch ($pids[$i]) {
        case -1:
            echo "fork error : {$i} \r\n";
            exit;
        case 0:
            $param = array(
                'lastid' => $max / $workers * $i,
                'maxid' => $max / $workers * ($i+1),
            );
            $this->executeWorker($input, $output, $param);
            exit;
        default:
            break;
    }
}
foreach ($pids as $i => $pid) {
    if($pid) {
        pcntl_waitpid($pid, $status);
    }
}*/
/*declare(ticks=1);
$bWaitFlag = FALSE; /// 是否等待进程结束
$intNum = 10;           /// 进程总数
$pids = array();        ///  进程PID数组
echo ("Start\n");
for($i = 0; $i < $intNum; $i++) {
    $pids[$i] = pcntl_fork();/// 产生子进程，而且从当前行之下开试运行代码，而且不继承父进程的数据信息
    if(!$pids[$i]) {
        // 子进程进程代码段_Start
        $str="";
        sleep(5+$i);
        for ($j=0;$j<$i;$j++) {$str.="*";}
        echo "$i -> " . time() . " $str \n";
        exit();
        // 子进程进程代码段_End
    }
}
if ($bWaitFlag)
{
    for($i = 0; $i < $intNum; $i++) {
        pcntl_waitpid($pids[$i], $status, WUNTRACED);
        echo "wait $i -> " . time() . "\n";
    }
}
echo ("End\n");*/
/*
   主任务管理器
   并发的执行子任务列表
*/
//开启的进程数
$exec_number = 40 ;
/***** main ********/
if($argc==1){
    echo("argv\n");
}
$taskfile = $argv[1];
//tasklist
$tasklist = file($taskfile);
$tasklist_len = count($tasklist);
$tasklist_pos = 0;
$handle_list = array();
while(1)
{
    //子进程列表有空闲,则填充补齐子进程列表
    if($exec_number > count($handle_list) && $tasklist_pos < $tasklist_len)
    {
        for($i=$tasklist_pos; $i<$tasklist_len; )
        {
            $command = $tasklist[$i] ;
            $handle_list[] = popen($command , "r" );
            $i++;
            if($exec_number == count($handle_list)) break;
        }
        $tasklist_pos = $i;
    }
    //如果子进程列表空，退出
    if(0 == count($handle_list))
    {
        break;
    }
    //检查子进程列表的输出，把停掉的子进程关闭并记录下来
    $end_handle_keys = array();
    foreach($handle_list as $key => $handle)
    {
        //$str = fgets($handle, 65536);
        $str = fread($handle, 65536);
        echo($str);
        if(feof($handle))
        {
            $end_handle_keys[] = $key;
            pclose($handle);
        }
    }
    //踢出停掉的子进程
    foreach($end_handle_keys as $key)
    {
        unset($handle_list[$key]);
        //var_dump($handle_list);
        //exit;
    }
}